import flixel.FlxSprite;
import flixel.FlxG;
import flixel.FlxObject;
import actions.ExecutableAction;
import actions.BasicContainer;
import flixel.tweens.FlxTween;
import flixel.tweens.FlxEase;
import actions.BasicContainer;

class ProgrammableActor extends FlxSprite{

	
	private static inline var TWEEN_DURATION: Float = 0.1;
	private static inline var STEP_SIZE: Float = 32;
	private static var TWEEN_EASING: EaseFunction = FlxEase.quadIn;
	private var direcction: Int;
	public var isTweening(default, null): Bool = false;
	private var _tween: FlxTween;
	private var _asociatedContainer: BasicContainer;
	private var _commandTimer: Float;
	public var finishedExecution(default, null): Bool;

	public function new(){
		super();
		
	}

	public function init_a(X: Float, Y: Float, AsociatedContainer: BasicContainer)
	{
		x = X;
		y = Y;
		_commandTimer = 0;
		//_asociatedContainer = AsociatedContainer;
		//_asociatedContainer.resetExecution();
		finishedExecution = false;
		moves = false;
	}


	private function ExecuteAction(action: String): Void {
		switch (action) {
			case "F":
				MoveForward();	

			case "L":
				RotateLeft();

			case "R":
				RotateRight();

			default:
				trace("Executing NOP...");
		}
	
	}


	override public function reset(X: Float, Y: Float){
		super.reset(X, Y);
		angle = 0;
		_commandTimer = 0;
		_tween = null;
		finishedExecution = false;
	}


	public function shoot(): Void {

	}

	private function MoveForward() {
		var options: TweenOptions = { type: FlxTween.ONESHOT, ease: TWEEN_EASING, complete: onEndTween};	
		isTweening = true;
		
		if(angle < 0) angle += 360;
		if(angle >= 360) angle -= 360;
		
		switch(angle){
			case 0:
				// mueve a la izquierda
				_tween = FlxTween.tween(this, {"x": this.x + STEP_SIZE}, TWEEN_DURATION, options);
			case 90:
				// mueve hacia abajo
				_tween = FlxTween.tween(this, {"y": this.y + STEP_SIZE}, TWEEN_DURATION, options);
			case 180:
				// mueve hacia la derecha
				_tween = FlxTween.tween(this, {"x": this.x - STEP_SIZE}, TWEEN_DURATION, options);
			case 270:
				// mueve hacia arriba
				_tween = FlxTween.tween(this, {"y": this.y - STEP_SIZE}, TWEEN_DURATION, options);
			default:
				throw("ProgrammableActor::moveForward(): Angulo inválido: "+angle);
		}
		
	}

	private function RotateLeft() {
		var options: TweenOptions = { type: FlxTween.ONESHOT, ease: TWEEN_EASING, complete: onEndTween};
		isTweening = true;
		_tween = FlxTween.tween(this, {angle: this.angle - 90}, TWEEN_DURATION, options);
	}

	private function RotateRight() {
		var options: TweenOptions = { type: FlxTween.ONESHOT, ease: TWEEN_EASING, complete: onEndTween};
		isTweening = true;
		_tween = FlxTween.tween(this, {angle: this.angle + 90}, TWEEN_DURATION, options);
	}

	private function onEndTween(tween: FlxTween): Void {
		isTweening = false;
		// evita que el actor collisione contra cosas con las que realmente no colisiona
		last.x = x;
		last.y = y;
	}

	public override function update(){
		_commandTimer += FlxG.elapsed;
		if(_commandTimer >= 1 && !isTweening){
			_commandTimer -= 1;
			if(_asociatedContainer.hasNext()){
				var action = _asociatedContainer.getNext();
				ExecuteAction(action.actionType);
			}else{
				finishedExecution = true;
				kill();
			}
			/// Ejecutar orden!!!
		}
	}


	public function setContainer(Container: BasicContainer)
	{
		_asociatedContainer = Container;
	}

}